package com.cse587.gae.dataconverter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.repackaged.com.google.common.collect.HashMultimap;
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import com.cse587.dao.CountryDao;
import com.cse587.entities.Country;
import com.cse587.entities.CountryBorder;
import com.cse587.entities.StatisticsInfo;
import com.cse587.util.SpringFactory;
import com.cse587.util.Util;

public class DBConvertor {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		//////////////////////////convert mysql database to google bigtable/////////////////////////////////////////
		SpringFactory sf = SpringFactory.getInstance();
		 CountryDao cDao = (CountryDao) sf.getInstance().getApplicationContext().getBean("countryDao");

		String username = "gassa0617@gmail.com";
		String password = "63319272";
		RemoteApiOptions options = new RemoteApiOptions().server("localhost",
				8888).credentials(username, password);
//		RemoteApiOptions options = new RemoteApiOptions().server(
//				"cse589-pro1-yinyan.appspot.com", 443).credentials(username,
//				password);
		
		RemoteApiInstaller installer = new RemoteApiInstaller();
		installer.install(options);
		List<Country> countryList = cDao.getALLCountry();
		    	
		try {
            DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
            
            HashMultimap<String, String> tokenToIsoMap = HashMultimap.create();
            for( int i=0; i<countryList.size();i++ ){
            	Transaction txn = ds.beginTransaction();
            	Country c = countryList.get(i);
                Entity country = new Entity("Country");
                //set basic property
                System.out.println("=========="+c.getFullName()+"====================");
                country.setProperty("fullName", c.getFullName());
                country.setProperty("codeISO3", c.getCodeISO3());
                country.setProperty("maxLat", c.getMaxLat());
                country.setProperty("maxLong", c.getMaxLong());
                country.setProperty("minLat", c.getMinLat());
                country.setProperty("minLong", c.getMinLong());
                country.setProperty("capital", c.getCapital());
                country.setProperty("uncode", c.getUnCode());
                country.setProperty("capitalLat", c.getCapitalLat());
                country.setProperty("capitalLong", c.getCapitalLong());
                //set alternative name
                //String[] alternativeName = cDao.getCountryAlternativename(c.getCodeISO3()).toLowerCase().split(" ");
                String alternativeNameString = cDao.getCountryAlternativename(c.getCodeISO3());
                Set<String> nameToke = Util.tokenCountryName(alternativeNameString, c);
                for (String token : nameToke) {
                	tokenToIsoMap.put(token, c.getCodeISO3());
				}
                
                String[] alternativeName = alternativeNameString.toLowerCase().split(",");
                System.out.println("alternative name:"+alternativeName.toString());
                List<String> list = Arrays.asList(alternativeName);
                Set<String> set = new HashSet<String>(list);
                country.setProperty("alternativeName", set);
                
                //set border property
                List<CountryBorder> borders = cDao.getCountryBorder(c.getCodeISO3());
                List<String> borderList = new ArrayList<String>();
                for (CountryBorder border : borders) {
                	borderList.add(border.getCid2());
    			}
                System.out.println("borders:"+borderList.toString());
                country.setProperty("borders", borderList);
                ds.put(txn, country);
                
                
                List<StatisticsInfo> infoList = cDao.getCountryStatInfo(c.getId());
                //add sub-entity statistic info 
                for( StatisticsInfo info: infoList ){
                	System.out.println(info.getPropertyName()+":"+info.getPropertyValue());
                	Entity infoEntity = new Entity(info.getPropertyName(), country.getKey());
            		infoEntity.setProperty("propertyValue", Double.valueOf(info.getPropertyValue()));
            		infoEntity.setProperty("year", info.getYear());
            		String indexname = info.getPropertyName().toLowerCase();
            		if( indexname.equals("landarea") ){
            			indexname = "landArea";
            		}
            		
            		infoEntity.setProperty(indexname+"_INTEGER_IDX", country.getKey());
            		ds.put(infoEntity);
                }
                txn. commit();
            }
            //build country name index
            
            for (String key : tokenToIsoMap.keySet()) {
            	Transaction txn = ds.beginTransaction();
            	Entity token = new Entity("CountryNameToken");
            	String term = key.toString();
            	System.out.println( key.getClass().toString() );
            	token.setProperty("token", term.toLowerCase());
            	Set<String> isoSet = new HashSet<String>();
            	isoSet.addAll(tokenToIsoMap.get(key));
            	token.setProperty("isoCodes", isoSet);
            	
            	ds.put(token);
            	txn. commit();
            }
            System.out.println("complete");    
        } finally {
            installer.uninstall();
        }

	}
	
}
